import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.digest.MD5;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import demoenum.ConstructParamName;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.poi.hssf.record.DVALRecord;
import org.junit.Assert;
import pojo.ScenePojo;
import pojo.TblScene;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.annotation.Nullable;
import javax.imageio.stream.FileImageOutputStream;
import javax.sql.rowset.spi.XmlWriter;
import java.awt.*;
import java.awt.print.Book;
import java.io.*;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class JavaOperations {
    public void testListDelete() throws Exception {
        List<String> sources = new ArrayList<>();
        sources.add("第1个");
        sources.add("第2个");
        sources.add("第3个");
        sources.add("第4个");
        sources.add("第5个");
        for (int idx = 0; idx < sources.size(); idx++) {
            System.out.println(idx + " : " + sources.get(idx));
        }
        System.out.println("=====Seperation=====");
        //下面的方式，在删除过程中会报错（而foreach更会报错）
//        for (int idx = 0; idx < sources.size(); idx++) {
//            //删除掉偶数位置
//            //测试删除奇数位置的内容，会报错，因为后续的索引已经超出了
//            //测试删除偶数时不报错，会打印出原本第2和第5个元素
//            if (idx%2==0) {
//                sources.remove(idx);
//                idx--;
//            }
//            //如果是第0个元素的话，会报错
//            if (idx>0) {
//                System.out.println(sources.get(idx));
//            }
//        }
        Iterator<String> itSource = sources.iterator();
        while (itSource.hasNext()) {
            String valueCurrent = itSource.next();
//            System.out.println(valueCurrent);
            //执行了删除之后，后续要素的索引一直在变化
            if (sources.indexOf(valueCurrent) % 2 != 0) {
                System.out.println(valueCurrent + " 将被删除");
                itSource.remove();
            }
        }
        System.out.println("执行删除操作后，立即遍历原始集合的结果：");
        System.out.println("新的集合大小：" + sources.size());
        for (int idx = 0; idx < sources.size(); idx++) {
            System.out.println(idx + " : " + sources.get(idx));
        }
    }

    public void testPointEquals() throws Exception {
        /*
         * 结论：
         * 从测试可以看出，Java的Point自身已经考虑了相等的判断，也就是实际所需要的情况
         * 描述为：当两个点的x和y都相等时才能认为两个点是同一个点
         * */
        Double disTolerance = 1e-8;
        Point pnt1 = new Point();
        pnt1.setLocation(3.141593, 5.723456);
        Point pnt2 = new Point();
        pnt2.setLocation(3.141592, 5.723457);
        System.out.println("原生方式判断");
        if (pnt1.equals(pnt2)) {
            System.out.println("小数位不一样时，两个点被判定为了相等。");
        } else {
            System.out.println("小数位不同时可以判断出两个点不相等");
        }
        if (pnt1.distance(pnt2) < disTolerance) {
            System.out.println("是同一个点");
            System.out.println(disTolerance.toString());
        }
        //自定义方法判断
        if (Point.distance(pnt1.getX(), pnt1.getY(), pnt2.getX(), pnt2.getY()) < disTolerance) {
            System.out.println("两个点是同一个点");
        } else {
            System.out.println("两个点不是同一个点");
        }
        Point pnt3 = new Point();
        pnt3.setLocation(3.141, 5.72);
        System.out.println(pnt3.x);
        System.out.println(pnt3.y);
    }

    public void testUsingHashCode() throws Exception {
        /*
         * 哈希值：两个对象的值不同，则哈希值一定不同，反之，哈希值相等时，其值不一定是相等的。
         * 因此在Java内部判断两个对象是否equals时，会先判断两个对象的哈希值，如果不相等，那么两个对象一定不相等；如果相等时才需要进一步判断equals的逻辑
         * */
        Point pnt = new Point();
        pnt.setLocation(2.345, 12.334);
        int testHash = pnt.hashCode();
        System.out.println(testHash);
        pnt = new Point();
        pnt.setLocation(77.6, 33.2);
        System.out.println(pnt.hashCode());
    }

    public void test二维数组() {
        int rowCounts = 4, columnCount = 4;
        String[][] demo = new String[rowCounts][columnCount];
        for (int i = 0; i < rowCounts; i++) {
            for (int j = 0; j < columnCount; j++) {
                demo[i][j] = String.valueOf(i) + String.valueOf(j);
            }
        }
        System.out.println("二维数组的length：" + demo.length);
        System.out.println("二维数组的列数length：" + demo[0].length);
        //从foreach上也可以看出来，怎样去获取二维数组的行列值
        //即：直接使用length获取的是行数；必须使用某一行的数组的length才是列的数量
        for (String[] rows : demo) {
            for (String column : rows) {
                System.out.print(column + "  ");
            }
            System.out.println(System.lineSeparator());
        }
    }

    public void test计算概率分布() {
        double x = 0.05;//这里的X是谁的值？是莫兰指数，还是其他的那个属性？
        //Parma1：平均值；Parma2：标准差
        NormalDistribution normalDistribution = new NormalDistribution(0.5, 3.2);
        System.out.println("数学期望：" + normalDistribution.getMean());
        System.out.println("方差：" + normalDistribution.getStandardDeviation());
        double v = normalDistribution.cumulativeProbability(x);
        v = Double.valueOf(String.format("%.8f", v));  //这里保存9位和vb中的WorksheetFunction.NORM.S.DIST(z,true)
        System.out.println("计算结果是：" + v);
    }

    public void testJava的复制() {
        double[][] arrSource = new double[3][3];
        Random random = new Random(10);
        DecimalFormat df = new DecimalFormat("#.000");
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                arrSource[i][j] = Double.valueOf(df.format(random.nextDouble()));
            }
        }
        System.out.println("原始数组是：");
        for (double[] row : arrSource) {
            for (double cln : row) {
                System.out.print(cln + "  ");
            }
            System.out.print(System.lineSeparator());
        }
        //===采用方法***===
//        double[][] arrCopy= Arrays.copyOf(arrSource,arrSource.length);
        double[][] arrCopy = new double[arrSource.length][];
        for (int i = 0; i < arrSource.length; i++) {
            arrCopy[i] = arrSource[i].clone();
        }
        //===采用clone的方式复制后，原始数组也发生了变化===
//        double[][] arrCopy = arrSource.clone();//二维数组是浅复制，只传递引用(一维数组是深复制)
        Arrays.sort(arrCopy[0]);//对复制后的数组第一行进行升序排列
        System.out.println("排序后的原始数组是：");
        for (double[] row : arrSource) {
            for (double cln : row) {
                System.out.print(cln + "  ");
            }
            System.out.print(System.lineSeparator());
        }
        System.out.println("排序后的新数组是：");
        for (double[] row : arrCopy) {
            for (double cln : row) {
                System.out.print(cln + "  ");
            }
            System.out.print(System.lineSeparator());
        }
        System.out.println("采用clone行法直接进行排序");
        for (double[] row : arrSource) {
            double[] rowCopy = row.clone();
            Arrays.sort(rowCopy);
            System.out.print(row[0] + "  ");
            System.out.print(rowCopy[0]);
            System.out.print(System.lineSeparator());
        }
    }

    public void test除法计算() {
        int n = 5;
        double value = (-1) / (n - 1);
        System.out.println("直接计算的结果：" + value);
        double value2 = (-1.0d) / (n - 1);//如果是想要double类型的结果，必须这么写
        System.out.println("转换后的计算结果：" + value2);
    }

    public void test度转为弧度() {
        double degree = 1;
        double radianMath = Math.toRadians(degree);
        System.out.println("Math转换结果：" + radianMath);
        double radianCalc = degree / 180 * Math.PI;
        System.out.println("Calculate转换结果：" + radianCalc);
    }

    public void test字符串分割() {
        //下面这种方式可以直接做到使用指定分隔符创建字符串
        StringJoiner builder=new StringJoiner("-");
        builder.add("first");
        builder.add("second");
        builder.add("third");
        System.out.println("长度："+builder.length());
        System.out.println("结果："+builder.toString());

        ////这种方式无法将1作为占位符，因为存在单引号
        //String tmp = MessageFormat.format("{0}='{1}'", "A", "B");
        //System.out.println("结果1：" + tmp);
        //String tmp2 = MessageFormat.format("{0}=\'{1}\'", "A", "B");//这种方式无法拼接单引号
        //System.out.println("结果2：" + tmp2);
        //String tmp3 = String.format("%s='%s'", "A", "B");//这一种可以拼接单引号到结果中
        //System.out.println("结果3：" + tmp3);
        //String srcPath = "E:\\vectorOutput\\mygeo2shp_1_1.xls";
        //String tmpjjjj = "jdbc:postgresql://localhost:5432/gisdb";
        ////无法直接使用.来作为分隔符，需要使用转义符而且是两个转义符
        //String[] ttttt = srcPath.split("\\.");
        //String[] ssssss = tmpjjjj.split("/");//此时一共分割成了4个数组，但是第二个是null
        //System.out.println("字符串分割结果：数量是：" + ttttt.length);
        //System.out.println("分割结果：" + ssssss[0] + ssssss[1] + ssssss[2] + ssssss[3]);
    }

    private void testDouble判断(Double pInput) {
        //必须这样子判断是否为null，Double.isNaN判断的是输入值是否是一个数字，而不是为null的判断
        if (pInput == null || Double.isNaN(pInput)) {
            System.out.println("传了null的Double");
        } else {
            System.out.println("输入的值是：" + pInput);
        }
    }

    public void testImageConversion() {
        String pathSvg = "E:\\9.3Puyang\\PuYang_POI_Data\\icon\\foodservice.svg";//svg暂时不支持
        String pathPng = "E:\\9.3Puyang\\PuYang_POI_Data\\Final_Data-Styles\\scenicspot.png";
        this.image2Base64(pathPng);
    }

    private void byte2Image(byte[] data, String path) {
        if (data.length < 3 || path.equals("")) return;
        try {
            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
            imageOutput.write(data, 0, data.length);
            imageOutput.close();
            System.out.println("Make Picture success,Please find image in " + path);
        } catch (Exception ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
        }
    }

    private void image2Base64(String imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            File tmpFile = new File(imgPath);
            System.out.println(tmpFile.getName());
            InputStream in = new FileInputStream(imgPath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
       String tttt = Base64.getEncoder().encodeToString(Objects.requireNonNull(data));
        // 返回Base64编码过的字节数组字符串
        System.out.println("本地图片转换Base64:" + encoder.encode(Objects.requireNonNull(data)));
    }

    public void testListToString() {
        List<String> sources = new ArrayList<String>();
        sources.add("第1个");
        sources.add("第2个");
        sources.add("第3个");
        sources.add("第4个");
        sources.add("第5个");
        System.out.println("toString的结果：");
        System.out.println("type01:" + sources.toString());
        System.out.println("type02:" + String.join(" ", sources));
        String pathSrc = "C:\\cygwin64\\bin\\mintty.exe";
        pathSrc = pathSrc.replace("\\", "/");//全部替换为Linux格式的路径，这个在Windows下本身也可以被识别
        System.out.println("转换后的路径：" + pathSrc);
    }

    public void testArrayToString() {
        double[] boundArray = new double[4];
        boundArray[0] = 2.1;
        boundArray[1] = 3.2;
        boundArray[2] = 4.3;
        boundArray[3] = 5.4;
//        System.out.println(boundArray.toString());
        String bounds = ArrayUtils.toString(boundArray, ",");
        System.out.println(bounds.substring(1, bounds.length() - 1));
        System.out.println(Arrays.toString(boundArray));
        System.out.println(ArrayUtils.toString(boundArray, ","));
        Assert.assertNull("该对象不是null", boundArray);
        System.out.println("最后一句");
    }

    public void testXML转换() throws IOException {
        ScenePojo response = new ScenePojo();
        response.setRequest("GetCapabilities,GetScene");
        response.setService("GIS Matrix Server powered by CMICT.");
        List<TblScene> tmpScenes = new ArrayList<>();
        TblScene perScene = new TblScene();
        perScene.setSceneId("001");
        perScene.setSceneName("第一个测试");
        perScene.setSceneDescription("为了测试对象重复的原因");
        perScene.addLayer("/layer01/01.shp", "layer测试名字1");
        perScene.addLayer("/layer01/02.shp", "第二个图层");
        tmpScenes.add(perScene);

        perScene = new TblScene();
        perScene.setSceneId("002");
        perScene.setSceneName("第2个测试");
        perScene.setSceneDescription("为了测试对象重复的原因2");
        tmpScenes.add(perScene);
        response.setScenes(tmpScenes);
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.setDefaultUseWrapper(false);
        System.out.println(xmlMapper.writeValueAsString(response));

    }

    public void testSubstring() {
        String src = "2cb2/8031cfb4e5a46a6b604671a8cd23_3";
        String resultStart = src.substring(src.lastIndexOf('_') + 1);
        String resultStart2End=src.substring(0,src.lastIndexOf("/"));
        System.out.println(resultStart);
        System.out.println(resultStart2End);
        System.out.println("=====");
        String fileName="2345.png";
        String filePath="4";
        if (fileName.substring(0,fileName.lastIndexOf(".")).matches("[0-9]+")) {
            System.out.println("能过滤文件");
        }
        if (filePath.substring(0,filePath.lastIndexOf(".")).matches("[0-9]+")) {
            System.out.println("能过滤文件夹");
        }
    }

    public boolean GenerateImage() {
        String tarImgPath = "F:\\gislogs\\thumbnail_02.png";
        String imgStrBase64 = "";
        String imgStr_02="";
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            String baseValue = imgStr_02.replaceAll(" ", "+");
            System.out.println(baseValue);
            byte[] b = decoder.decodeBuffer(baseValue.replace("data:image/jpeg;base64,", ""));
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            File targetFile = new File(tarImgPath);
            OutputStream out = new FileOutputStream(targetFile);
            out.write(b);
            out.flush();
            out.close();
//            image2Base64(tarImgPath);
            System.out.println("执行完毕");
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public void tmp路径遍历漏洞修复(){
        String pathSource="/safe_dir/..//important.txt";
        String path2="E:\\9.10公司其他工作\\2.鲲鹏认证-GIS平台\\..\\材料补充及修改\\non.txt";
        String safePath=fileNameValidate(path2);
        System.out.println("处理后的结果："+safePath);
        System.out.println("win下的路径："+path2);
        System.out.println("=====字符串数组直接转字符串=====");
        String[] tttCommand=new String[5];
        tttCommand[0]="aa";
        tttCommand[1]="ext";
        tttCommand[2]="cc";
        tttCommand[3]="mm";
        tttCommand[4]="qq";
        System.out.println("直接转的结果："+tttCommand.toString());//不能直接转
        StringBuilder builder=new StringBuilder();
        for (String per : tttCommand) {
            builder.append(per+" ");
        }
        System.out.println("build的结果："+builder.toString());
    }

    private String fileNameValidate(String pathSource) {
        String illegalChars = "../|./|/..";  //这里为请求体中不能携带的关键字
        List<String> illegalChars2=new ArrayList<>();
        illegalChars2.add("../");
        illegalChars2.add("./");
        illegalChars2.add("/..");
        illegalChars2.add("..\\");
        illegalChars2.add(".\\");
        illegalChars2.add("\\..");
        if (null != illegalChars && !"".equals(illegalChars)) {
            pathSource = pathSource.toLowerCase();// 统一转为小写
            for (String perIllegalChar : illegalChars2) {
                if (pathSource.indexOf(perIllegalChar)>=0) {
//                    throw new IllegalArgumentException("传入的路径["+pathSource+"]非法，请检查.");
                    return perIllegalChar;
                }
            }
        }
        return null;
    }

    public void test加密解密() throws UnsupportedEncodingException {
        //String passSource = "gisAdmin@10086";
        //String encrypted = encryptWithHashCode(passSource);
        //System.out.println("Java加密后：" + encrypted);
        //System.out.println("Java解密后：" + encryptWithHashCode(encrypted));
        String pwdEncrypt=encryptCustomize("gisAdmin@10086");
        System.out.println("加密结果："+pwdEncrypt);
        System.out.println("解密结果："+decryptCustomize(pwdEncrypt));
        String alterPwd=encryptCustomize("gis.matrix.server");
        System.out.println("修改后的密码："+alterPwd);
        //System.out.println("使用前台传递结果的解密："+decryptCustomize("02V02X03701T02S03102X03201S01D01C01C01K01I"));
        //System.out.println("自定义加密算法结果："+encryptCustomize("gisAdmin@10086"));
        //不能用于后台加密
        //System.out.println(decryptCustomize("gisAdmin@10086"));
    }

    //private final String key="1234567890.@#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private final String key="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public String decryptCustomize(String input){
        //String key="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] chars=new char[input.length()/3];
        int operator=0;
        for (int idx = 0; idx < chars.length; idx++) {
            int b1 = key.indexOf(input.charAt(operator));
            operator++;
            int b2 = key.indexOf(input.charAt(operator));
            operator++;
            int b3=key.indexOf(input.charAt(operator));
            operator++;
            chars[idx]= (char) (b1*key.length()*key.length()+b2*key.length()+b3);
        }
        return new String(chars);
    }

    private String encryptCustomize(String input){
        //String key="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        //定义密钥，36个字母和数字
        int l = key.length();  //获取密钥的长度
        String[] a = key.split("");  //把密钥字符串转换为字符数组
        //String s = "",b, b1, b2, b3;  //定义临时变量
        String s="";
        for (int i = 0; i <input.length(); i ++) {  //遍历字符串
            //b = input.charCodeAt(i);  //逐个提取每个字符，并获取Unicode编码值
           char b=input.charAt(i);//逐个提取每个字符，并获取Unicode编码值
            int b1 = b % l;//求Unicode编码值得余数
            b = (char) ((b - b1) / l);  //求最大倍数
            int b2 = b % l;  //求最大倍数的余数
            b = (char) ((b - b2) / l);  //求最大倍数
            int b3 = b % l;  //求最大倍数的余数
            s += a[b3] + a[b2] + a[b1];  //根据余数值映射到密钥中对应下标位置的字符
        }
        return s;  //返回这些映射的字符

    }

    private String encryptWithHashCode(String pass){
        String key = "gis.matrix.server";
        System.out.println("key hashCode:"+key.hashCode());
        char[] charsMiddle=pass.toCharArray();
        for (int idxPass = 0; idxPass < charsMiddle.length; idxPass++) {
            charsMiddle[idxPass]= ((char) (charsMiddle[idxPass] ^ key.hashCode()));
        }
        return new String(charsMiddle);
    }

    public void test数组传入参数() {
        String info="失败";
        Boolean flag=false;
        this.innerTest(new Object[]{flag,info});
    }

    private void innerTest(Object input){
        Object[] tt1= (Object[]) input;
        System.out.println(Boolean.valueOf(tt1[0].toString()));
        System.out.println(tt1[1].toString());
    }

    private static List<String> tileName=new ArrayList<>();
    public void test删除切片数据(){
        String tileRootPath="F:\\gislogs\\tile03";
        for (int i = 0; i <19 ; i++) {
            tileName.add(String.valueOf(i));
        }
        delAllFile(tileRootPath);
    }


    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            //因为切片的文件夹和文件的名称一定是纯数字，所以一定要过滤
            if (!tempList[i].matches("[0-9]+")) {
                System.out.println(tempList[i]+"->file not");
                continue;
            }
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                tempList[i].lastIndexOf(".");
                boolean result= temp.delete();
                if (!result) {
                    System.out.println(temp.getName()+"->删除file失败.");
                }
            }
            if (temp.isDirectory()) {
//                System.out.println("delete file: "+tempList[i]);
                delAllFile(path + File.separator + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + File.separator + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
//            System.out.println("delete folder: "+filePath);
            boolean result= myFilePath.delete(); // 删除空文件夹
            if (!result) {
                System.out.println(myFilePath.getName()+"->删除folder失败.");
            }else {
                System.out.println(myFilePath.getName()+"->成功删除folder");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void test判断文件类型(){
        String pathSrc="F:\\97-LocalDeploy\\Redis-x64-5.0.10\\redis-server.pdb";
        File file= FileUtil.file(pathSrc);
        String type = FileTypeUtil.getType(file);
        System.out.println("Hutool获取的文件类型："+type);
    }
    public void test判断字符串包含(){
        String srcString="/gis/swagger-ui.html";
        Boolean flag0=srcString.matches(".+[wagger]+");
        System.out.println("flag0:"+flag0);
        int idx_Swagger = srcString.lastIndexOf("swaggerui");
        System.out.println("idx_Swagger:"+idx_Swagger);


        String str4 = "/gis/csrf";
        int idx_csrf = str4.indexOf("/gis/csrf");
        System.out.println("idx_csrf:"+idx_csrf);

        String str21 = "123qwe123qwe";
        boolean flag23 = str21.matches("^(3qw)+");
        System.out.println(flag23);

        String str20 = "mmmabc123abc";
        boolean flag22 = str20.matches("(abc|123){3}");
        System.out.println("flag22:"+flag22);

        String str11 = "fdfeetg  34566";
        boolean flag11 = str11.matches("[fdfeetg]+//s+[3-6]+");
        System.out.println("flag11:"+flag11);
    }

    public void test时间类型的对象() throws InterruptedException {
        LocalTime timeUnlock = LocalTime.now().plusSeconds(10);
        int secondBegin = LocalTime.now().getSecond();
        System.out.println("当前时间是："+LocalTime.now());
        Thread.sleep(10000);
        int secondEnd = LocalTime.now().getSecond();
        if (LocalTime.now().isAfter(timeUnlock)) {
            System.out.println("已经到了解锁时间");
        }
        System.out.println("时间差："+(secondEnd - secondBegin));
    }

    public void test枚举类型(){
        System.out.println("ConstructParamName.SourceDataStore方式："+ConstructParamName.SourceDataStore);
        System.out.println(ConstructParamName.SourceDataStore.name());
        System.out.println(ConstructParamName.SourceDataStore.ordinal());
        Map<ConstructParamName,Object> demoList=new HashMap<>();
        demoList.put(ConstructParamName.SourceDataStore,"DataStore对象");
        demoList.put(ConstructParamName.SourceGeometryColumnName,"geom");
        for (Map.Entry<ConstructParamName, Object> perChild : demoList.entrySet()) {
            System.out.print(perChild.getKey());
            System.out.print(" : ");
            System.out.print(perChild.getValue());
            System.out.print(System.lineSeparator());
        }
    }

    private final HashSet<String> allowedExtensions = new HashSet<String>() {{
        //shp类型的矢量文件
        addAll(Arrays.asList("shp", "shx", "prj", "dbf", "cpg", "qix", "fix", "sbn"));
        //GeoJson类型的矢量文件
        addAll(Arrays.asList("json", "geojson"));
        //栅格数据
        addAll(Arrays.asList("tif", "ovr", "img", "image", "tiff", "dem"));
        //样式文件
        add("sld");
        //其他GIS数据类型
        addAll(Arrays.asList("pbf", "kml", "osgb", "dxf", "dwg"));
    }};
    public void test正则表达式验证(){
        Pattern patternFilter = Pattern.compile("0-9.-");
        Double tdouble=-123.4;
        //Matcher matcher1 = patternFilter.matcher(tdouble);
        //下面这个正则表达式是验证一个合法的网址
        Pattern patternFilter2 = Pattern.compile("^((http|https|hdfs|ftp)://)?([\\w-]+.)+[\\w-]+(/[\\w-./?%&=]*)?$");
        String input="hdfs://192.168.108.50:8020";
        Matcher matcher = patternFilter.matcher(input);
        if (matcher.matches()) {
            System.out.println("验证通过");
        }else {
            System.out.println("包含非法字符");
        }

        HashSet<String> files = new HashSet<String>(
                Arrays.asList("123.shp", "123.cpg", "123.dbf", "123.prj", "123.shx"));
        for (String perFile : files) {
            String sub = perFile.substring(perFile.lastIndexOf('.') + 1);
            System.out.println(sub);
            if (this.allowedExtensions.contains(sub)) {
                System.out.println("合法GIS数据");
            }else {
                System.out.println("不合法数据");
            }
        }
    }

    public void test获取Jar包路径() throws IOException {
        URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
        String filePath = null;
        try {
            System.out.println("0： "+this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
            String path = url.toURI().getPath();
            System.out.println("1："+ path);
            path=path.substring(0,path.length()-2);
            System.out.println("1.2: "+path);
            System.out.println("2: "+System.getProperty("user.home"));
            System.out.println("3: "+System.getProperty("user.dir"));//最后没有路径符
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("----------");
        try {
            String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
            path = java.net.URLDecoder.decode(path, "UTF-8");
            File file = new File(path);
            if (file.isFile()) {
                System.out.println("result01: "+file.getParent());
            }else {
                System.out.println("result02: "+file.getPath());
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        System.out.println("-----------");
        System.out.println(File.separator);//动态获取不同平台的路径分隔符
        String tmp="hello";
        //从结果可以判断：substring是包含beginIndex而不包含endIndex的
        System.out.println(tmp.substring(0, tmp.length() - 1));//输出hell
    }
}
